/*
Copyright (C) 2013-2021 LZE
Prog:Segment Tree 
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn = 100010;
ll n,m,a[maxn];
ll Tree[maxn << 2],tag[maxn << 2];
void build(ll p,ll l,ll r){
    if(l == r){
        Tree[p] = a[l];
        return;
    }
    ll mid = (l + r) >> 1;
    build(p << 1,l,mid);
    build(p << 1 | 1,mid + 1,r);
    Tree[p] = Tree[p << 1] + Tree[p << 1 | 1];
}
void push_down(ll p,ll l,ll r){
    ll mid = (l + r) >> 1;
    tag[p << 1] += tag[p];
    tag[p << 1 | 1] += tag[p];
    Tree[p << 1] += tag[p] * (mid - l + 1);
    Tree[p << 1 | 1] += tag[p] * (r - mid);
    tag[p] = 0;
}
void update(ll p,ll l,ll r,ll L,ll R,ll val){
    if(R < l || r < L)return;
    if(L <= l && r <= R){
        Tree[p] += val * (r - l + 1);
        tag[p] += val;
        return;
    }
    ll mid = (l + r) >> 1;
    push_down(p,l,r);
    if(R <= mid)update(p << 1,l,mid,L,R,val);
    else if(L > mid)update(p << 1 | 1,mid + 1,r,L,R,val);
    else{
        update(p << 1,l,mid,L,R,val);
        update(p << 1 | 1,mid + 1,r,L,R,val);
    }
    Tree[p] = Tree[p << 1] + Tree[p << 1 | 1];
}
ll query(ll p,ll l,ll r,ll L,ll R){
    if(R < l || r < L)return 0;
    if(L <= l && r <= R)return Tree[p];
    ll mid = (l + r) >> 1;
    push_down(p,l,r);
    if(R <= mid)return query(p << 1,l,mid,L,R);
    else if(L > mid)return query(p << 1 | 1,mid + 1,r,L,R);
    else{
        return query(p << 1,l,mid,L,R) + query(p << 1 | 1,mid + 1,r,L,R);
    }
}
int main(){
    scanf("%lld%lld",&n,&m);
    for(ll i = 1;i <= n;i++)scanf("%lld",&a[i]);
    ll act,x,y,k;
    build(1,1,n);
    for(ll i = 1;i <= m;i++){
        scanf("%lld",&act);
        switch(act){
            case 1:{
                scanf("%lld%lld%lld",&x,&y,&k);
                update(1,1,n,x,y,k);
                break;
            }
            case 2:{
                scanf("%lld%lld",&x,&y);
                printf("%lld\n",query(1,1,n,x,y));
                break;
            }
        }
    }
    return 0;
}